package com.yeung.swordoffer;

import com.yeung.exam.ReadUtils;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 * 题目描述
 * 请实现两个函数，分别用来序列化和反序列化二叉树
 * <p>
 * 二叉树的序列化是指：把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串，
 * 从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改，
 * 序列化的结果是一个字符串，序列化时通过 某种符号表示空节点（#），以 ！ 表示一个结点值的结束（value!）。
 * <p>
 * 二叉树的反序列化是指：根据某种遍历顺序得到的序列化字符串结果str，重构二叉树。
 */
public class 序列化二叉树 {
    public static void main(String[] args) {
        TreeNode root = Deserialize("2!4!5!#!#!7!#!#!8!#!6!#!#!");
        System.out.println(root);
    }

    static String Serialize(TreeNode root) {
        //采用先序遍历
        if (root == null) return "#!";

        String str = root.val + "!";
        str += Serialize(root.left);
        str += Serialize(root.right);
        return str;

    }

    static TreeNode Deserialize(String str) {
        int[] nums = ReadUtils.str2Int(str.replaceAll("#", "-1"), "!");
        Queue<Integer> queue = new ArrayDeque<Integer>();
        for (int num : nums) {
            queue.add(num);
        }
        return deserializeTree(queue);
    }

    static TreeNode deserializeTree(Queue<Integer> queue) {
        if (queue.size() == 0) return null;
        int data = queue.poll();
        if (data == -1) return null;//空树
        TreeNode root = new TreeNode(data);
        root.left = deserializeTree(queue);
        root.right = deserializeTree(queue);
        return root;
    }

}
